﻿Public Class FileMng_RCLog
    Inherits FileMng

    Public Property listCategories As List(Of RCLogCategory)
    Public Property listAppenders As List(Of RCLogAppender)
    Public Property oRCLogConfig As RCLogConfig
    Public Property strVersion As String


    Public Sub New()
        listCategories = New List(Of RCLogCategory)
        listAppenders = New List(Of RCLogAppender)
        oRCLogConfig = New RCLogConfig
    End Sub

#Region "Utility"

    Public Overrides Sub Clear()
        listCategories.Clear()
        listAppenders.Clear()
        oRCLogConfig.Clear()
        strVersion = ""
    End Sub

    ''' <summary>
    ''' Clean string removing tabs, spaces, "" and ,
    ''' </summary>
    Private Overloads Function CleanString(ByVal inText As String) As String
        Call MyBase.CleanString(inText)

        Dim intPosition As Integer = inText.IndexOf("""")

        While intPosition > -1
            inText = inText.Remove(intPosition, 1)
            intPosition = inText.IndexOf("""")
        End While

        If inText.Trim.EndsWith(",") Then
            inText = inText.Substring(0, inText.Length - 1)
        End If

        Return inText.Trim
    End Function

    ''' <summary>
    ''' Get priority number from string 
    ''' </summary>
    Private Function GetPriority(ByVal inPriority As String)
        Select Case inPriority.ToUpper
            Case "FATAL" : Return RCLogCategory.Priority.ePriority_FATAL
            Case "ERROR" : Return RCLogCategory.Priority.ePriority_ERROR
            Case "WARN" : Return RCLogCategory.Priority.ePriority_WARN
            Case "INFO" : Return RCLogCategory.Priority.ePriority_INFO
            Case "DEBUG" : Return RCLogCategory.Priority.ePriority_DEBUG
            Case "TRACE" : Return RCLogCategory.Priority.ePriority_TRACE
            Case Else : Return 0
        End Select
    End Function

    Public Function MustSynchronize(ByRef inOtherObj As FileMng_RCLog) As Boolean
        If listCategories.Count <> inOtherObj.listCategories.Count Then
            Return True
        End If

        Return False
    End Function

#End Region

#Region "Load File Main"

    Private Function GetListCategories(ByVal inTest() As String, ByVal inBlocker As String, ByRef outRowNo As Integer) As Boolean
        Dim strNameCategory As String = ""

        For Each strLine As String In inTest
            If strLine.IndexOf(inBlocker) > -1 Then
                Call SplitAttribute(strLine, "=", "", strNameCategory)
                strNameCategory = strNameCategory.Trim.Substring(1, strNameCategory.Trim.Length - 3)

                Me.listCategories.Add(New RCLogCategory(strNameCategory, 0, ""))
            End If
        Next

        Return True
    End Function

    Public Overrides Function ReadSourceFile(ByRef inText() As String) As Boolean
        Try
            Dim blnRet As Boolean = True
            Dim intRowError As Integer = 0
            
            ' Load categories
            blnRet = GetListCategories(inText, "static const PCHAR", intRowError)
            If blnRet = False Then
                strErrorMsg = "Error to read categories" & vbCrLf & "Line = " & intRowError
                Return False
            End If

            Return True
        Catch ex As Exception
            strErrorMsg = "Error to read file RCLoggerDefs.h"
            Return False
        End Try
    End Function

#End Region

#Region "Load File"

    Private Function GetListCategoriesFromRCLog(ByVal inTest() As String, ByRef outRowNo As Integer) As Boolean
        For i As Integer = 0 To inTest.Count - 1
            If inTest(i).IndexOf("version") > -1 Then
                ' read version
                If Not SplitAttribute(inTest(i), ":", "", strVersion) Then
                    outRowNo = i
                    Return False
                End If
                strVersion = CleanString(strVersion)

            ElseIf inTest(i).IndexOf("config") > -1 Then
                ' read readThreadPriority
                i += 1
                Dim strReadThreadPriority As String = ""
                If Not SplitAttribute(inTest(i), ":", "", strReadThreadPriority) Then
                    outRowNo = i + 1
                    Return False
                End If
                oRCLogConfig.intReadThreadPriority = CInt(CleanString(strReadThreadPriority))

                ' read readThreadPriority
                i += 1
                Dim strTempEventsBufSize As String = ""
                If Not SplitAttribute(inTest(i), ":", "", strTempEventsBufSize) Then
                    outRowNo = i + 1
                    Return False
                End If
                oRCLogConfig.intTempEventsBufSize = CInt(CleanString(strTempEventsBufSize))

                ' read readThreadPriority
                i += 1
                Dim strReaderStatus As String = ""
                If Not SplitAttribute(inTest(i), ":", "", strReaderStatus) Then
                    outRowNo = i + 1
                    Return False
                End If
                oRCLogConfig.strReaderStatus = CleanString(strReaderStatus)

            ElseIf inTest(i).IndexOf("category") > -1 Then
                ' read categories
                i += 1
                Do While inTest(i).Trim <> "],"
                    If inTest(i).IndexOf("name") > -1 Then
                        Dim strNameCategory As String = ""
                        Dim strPriority As String = ""
                        Dim intPriority As RCLogCategory.Priority
                        Dim strAppender As String = ""

                        ' read name category
                        If Not SplitAttribute(inTest(i), ":", "", strNameCategory) Then
                            outRowNo = i
                            Return False
                        End If
                        strNameCategory = CleanString(strNameCategory)

                        ' read priority
                        i += 1
                        If Not SplitAttribute(inTest(i), ":", "", strPriority) Then
                            outRowNo = i + 1
                            Return False
                        End If
                        strPriority = CleanString(strPriority)
                        intPriority = GetPriority(strPriority)

                        ' read appender
                        i += 1
                        If Not SplitAttribute(inTest(i), ":", "", strAppender) Then
                            outRowNo = i + 1
                            Return False
                        End If
                        strAppender = CleanString(strAppender)

                        Me.listCategories.Add(New RCLogCategory(strNameCategory, intPriority, strAppender))

                        If strNameCategory = "RCE_Trajectories.Profiles" Then
                            strAppender = ""
                        End If
                    End If

                    i += 1
                Loop

            ElseIf inTest(i).IndexOf("appender") > -1 Then
                ' read appenders
                i += 1
                Do While inTest(i).Trim <> "]"
                    If inTest(i).IndexOf("name") > -1 Then
                        Dim strNameAppender As String = ""
                        Dim strType As String = ""

                        ' read name appender
                        If Not SplitAttribute(inTest(i), ":", "", strNameAppender) Then
                            outRowNo = i
                            Return False
                        End If
                        strNameAppender = CleanString(strNameAppender)

                        ' read type
                        i += 1
                        If Not SplitAttribute(inTest(i), ":", "", strType) Then
                            outRowNo = i + 1
                            Return False
                        End If
                        strType = CleanString(strType)

                        Me.listAppenders.Add(New RCLogAppender(strNameAppender, strType))

                    End If

                    i += 1
                Loop

            End If
        Next

        Return True
    End Function

    Public Overrides Function ReadFile(ByRef inText() As String) As Boolean
        Try
            Dim blnRet As Boolean = True
            Dim intRowError As Integer = 0

            blnRet = GetListCategoriesFromRCLog(inText, intRowError)
            If blnRet = False Then
                strErrorMsg = "Error to read RCLog structure" & vbCrLf & "Line = " & intRowError
                Return False
            End If

            Return True
        Catch ex As Exception
            strErrorMsg = "Error to read file RCLog"
            Return False
        End Try
    End Function

#End Region

#Region "Save file"

    Public Overrides Function SaveFile(ByVal inFilePath As String) As Boolean
        Try
            Dim strFileContent As String = ""
            Call GenerateFile(strFileContent)

            Dim oWriter As New IO.StreamWriter(inFilePath)

            oWriter.WriteLine(strFileContent)
            oWriter.Close()

            oWriter = Nothing

            Return True
        Catch ex As Exception
            strErrorMsg = "Error to save file RCLog"
            Return False
        End Try
    End Function

#End Region

#Region "Generate file"

    Public Overrides Function GenerateFile(ByRef outFile As String) As Boolean
        Dim intIndex As Integer = 1
        Dim strBuilder As New System.Text.StringBuilder

        ' Open
        strBuilder.Append("{" & vbCrLf)

        ' Header
        strBuilder.Append(String.Format(String.Format("{0}""version"": ""{1}"",{2}", vbTab, strVersion, vbCrLf)))

        ' Config
        strBuilder.Append(String.Format("{0}""config"": {1}{2}", vbTab, "{", vbCrLf))
        strBuilder.Append(String.Format("{0}{0}""readThreadPriority"": {1},{2}", vbTab, oRCLogConfig.intReadThreadPriority, vbCrLf))
        strBuilder.Append(String.Format("{0}{0}""tempEventsBufSize"": {1},{2}", vbTab, oRCLogConfig.intTempEventsBufSize, vbCrLf))
        strBuilder.Append(String.Format("{0}{0}""readerStatus"": ""{1}""{2}", vbTab, oRCLogConfig.strReaderStatus, vbCrLf))
        strBuilder.Append("}," & vbCrLf)

        ' Categories
        strBuilder.Append(String.Format("{0}""category"": [{1}", vbTab, vbCrLf))
        intIndex = 1
        For Each oCategory As RCLogCategory In Me.listCategories
            strBuilder.Append(String.Format("{0}{0}{1}{2}", vbTab, "{", vbCrLf))
            strBuilder.Append(String.Format("{0}{0}{0}""name"": ""{1}"",{2}", vbTab, oCategory.strName, vbCrLf))
            strBuilder.Append(String.Format("{0}{0}{0}""priority"": ""{1}"",{2}", vbTab, oCategory.GetPriority.ToLower, vbCrLf))
            strBuilder.Append(String.Format("{0}{0}{0}""appender"": ""{1}""{2}", vbTab, oCategory.strAppender, vbCrLf))
            If intIndex = listCategories.Count Then
                strBuilder.Append(String.Format("{0}{0}{1}{2}", vbTab, "}", vbCrLf))
            Else
                strBuilder.Append(String.Format("{0}{0}{1},{2}", vbTab, "}", vbCrLf))
            End If
            intIndex += 1
        Next
        strBuilder.Append(String.Format("{0}],{1}", vbTab, vbCrLf))

        ' Appenders
        intIndex = 1
        strBuilder.Append(String.Format("{0}""appender"": [{1}", vbTab, vbCrLf))
        For Each oAppender As RCLogAppender In Me.listAppenders
            strBuilder.Append(String.Format("{0}{0}{1}{2}", vbTab, "{", vbCrLf))
            strBuilder.Append(String.Format("{0}{0}{0}""name"": ""{1}"",{2}", vbTab, oAppender.strName, vbCrLf))
            strBuilder.Append(String.Format("{0}{0}{0}""type"": ""{1}""{2}", vbTab, oAppender.strType, vbCrLf))
            If intIndex = listAppenders.Count Then
                strBuilder.Append(String.Format("{0}{0}{1}{2}", vbTab, "}", vbCrLf))
            Else
                strBuilder.Append(String.Format("{0}{0}{1},{2}", vbTab, "}", vbCrLf))
            End If
            intIndex += 1
        Next
        strBuilder.Append(String.Format("{0}]{1}", vbTab, vbCrLf))
        strBuilder.Append("}" & vbCrLf)

        outFile = strBuilder.ToString

        Return True
    End Function

#End Region

End Class
